<template>
  <div style="width: 100%; height: 100%; position: relative">
    <iframe
      :src="computedSrc"
      :name="props.name"
      :title="props.title"
      :sandbox="props.sandbox"
      :allow="props.allow"
      :referrerpolicy="props.referrerPolicy"
      :loading="props.loading"
      :style="getIframeStyle()"
      @load="handleLoad"
      @error="handleError"
    />

    <!-- 加载状态 -->
    <div v-if="isLoading" class="iframe-loading" :style="getLoadingStyle()">
      <div class="loading-spinner"></div>
      <span class="loading-text">{{ props.loadingText }}</span>
    </div>

    <!-- 错误状态 -->
    <div v-if="hasError" class="iframe-error" :style="getErrorStyle()">
      <div class="error-icon">⚠️</div>
      <div class="error-message">
        <h3>加载失败</h3>
        <p>{{ props.errorText }}</p>
        <div class="error-tips">
          <h4>常見原因：</h4>
          <ul>
            <li>• 网站禁止在 iframe 中加载（如：百度、谷歌）</li>
            <li>• 网络连接问题或网址无效</li>
            <li>• 混合内容安全策略限制</li>
          </ul>
          <p><strong>建议尝试：</strong> w3schools.com, developer.mozilla.org</p>
        </div>
      </div>
      <button v-if="props.showRetry" class="retry-button" @click="retry">重试</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue';

const props = defineProps({
  src: {
    type: String,
    default: 'https://www.example.com',
    required: true
  },
  name: {
    type: String,
    default: ''
  },
  title: {
    type: String,
    default: 'Iframe Content'
  },
  sandbox: {
    type: String,
    default: 'allow-same-origin allow-scripts allow-popups allow-forms'
  },
  allow: {
    type: String,
    default: ''
  },
  referrerPolicy: {
    type: String as () =>
      | 'no-referrer'
      | 'no-referrer-when-downgrade'
      | 'origin'
      | 'origin-when-cross-origin'
      | 'same-origin'
      | 'strict-origin'
      | 'strict-origin-when-cross-origin'
      | 'unsafe-url',
    default: 'no-referrer-when-downgrade'
  },
  loading: {
    type: String as () => 'eager' | 'lazy',
    default: 'lazy'
  },
  width: {
    type: [String, Number],
    default: '100%'
  },
  height: {
    type: [String, Number],
    default: '100%'
  },
  border: {
    type: String,
    default: 'none'
  },
  borderRadius: {
    type: String,
    default: '0'
  },
  autoResize: {
    type: Boolean,
    default: true
  },
  loadingText: {
    type: String,
    default: '正在加载...'
  },
  errorText: {
    type: String,
    default: '加载失败，请检查网络连接或URL是否正确'
  },
  showRetry: {
    type: Boolean,
    default: true
  },
  enableFullscreen: {
    type: Boolean,
    default: false
  },
  backgroundColor: {
    type: String,
    default: '#ffffff'
  }
});

const emit = defineEmits(['load', 'error', 'resize']);

const isLoading = ref(true);
const hasError = ref(false);
const retryCount = ref(0);
const loadTimeout = ref<NodeJS.Timeout | null>(null);

const computedSrc = computed(() => {
  // 检查URL是否有效
  const url = props.src.trim();
  if (
    !url ||
    (!url.startsWith('http://') && !url.startsWith('https://') && !url.startsWith('data:'))
  ) {
    return 'data:text/html;charset=utf-8,<html><head><meta charset="UTF-8"></head><body style="font-family: Arial, sans-serif; text-align: center; padding: 50px; background: #f5f5f5;"><h3 style="color: #333;">请输入有效的网页地址</h3><p style="color: #666;">URL应该以 http:// 或 https:// 开头</p></body></html>';
  }

  // 添加时间戳防止缓存，用于重试
  if (retryCount.value > 0) {
    const separator = url.includes('?') ? '&' : '?';
    return `${url}${separator}_t=${Date.now()}`;
  }
  return url;
});

const getIframeStyle = () => {
  const style: Record<string, string> = {
    width: typeof props.width === 'number' ? `${props.width}px` : props.width,
    height: typeof props.height === 'number' ? `${props.height}px` : props.height,
    border: props.border,
    borderRadius: props.borderRadius.includes('px')
      ? props.borderRadius
      : `${props.borderRadius}px`,
    backgroundColor: props.backgroundColor,
    display: isLoading.value || hasError.value ? 'none' : 'block'
  };

  if (props.enableFullscreen) {
    style.allowfullscreen = 'true';
  }

  return style;
};

const getLoadingStyle = () => {
  return {
    position: 'absolute' as const,
    top: '0',
    left: '0',
    width: '100%',
    height: '100%',
    display: 'flex',
    flexDirection: 'column' as const,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: props.backgroundColor,
    zIndex: '10'
  };
};

const getErrorStyle = () => {
  return {
    position: 'absolute' as const,
    top: '0',
    left: '0',
    width: '100%',
    height: '100%',
    display: 'flex',
    flexDirection: 'column' as const,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: props.backgroundColor,
    zIndex: '10',
    color: '#666',
    textAlign: 'center' as const,
    padding: '20px'
  };
};

const handleLoad = (event: Event) => {
  if (loadTimeout.value) {
    clearTimeout(loadTimeout.value);
    loadTimeout.value = null;
  }
  isLoading.value = false;
  hasError.value = false;
  emit('load', event);
  console.log('Iframe loaded successfully');
};

const handleError = (event: Event) => {
  if (loadTimeout.value) {
    clearTimeout(loadTimeout.value);
    loadTimeout.value = null;
  }
  isLoading.value = false;
  hasError.value = true;
  emit('error', event);
  console.log('Iframe load error:', event);
};

const retry = () => {
  retryCount.value++;
  isLoading.value = true;
  hasError.value = false;
  startLoadingTimeout();
  console.log(`Retrying iframe load, attempt ${retryCount.value}`);
};

// 设置加载超时
const startLoadingTimeout = () => {
  if (loadTimeout.value) {
    clearTimeout(loadTimeout.value);
  }

  loadTimeout.value = setTimeout(() => {
    if (isLoading.value) {
      console.warn('Iframe load timeout');
      isLoading.value = false;
      hasError.value = true;
    }
  }, 5000); // 5秒超时，更快反馈
};

// 监听src变化，重新加载
watch(
  () => props.src,
  () => {
    isLoading.value = true;
    hasError.value = false;
    retryCount.value = 0;
    startLoadingTimeout();
  }
);

// 自适应高度功能（可选）
let resizeObserver: ResizeObserver | null = null;

onMounted(() => {
  // 开始加载超时计时
  startLoadingTimeout();

  if (props.autoResize && window.ResizeObserver) {
    resizeObserver = new ResizeObserver((entries) => {
      for (const entry of entries) {
        emit('resize', {
          width: entry.contentRect.width,
          height: entry.contentRect.height
        });
      }
    });

    const container = document.querySelector('.iframe-container');
    if (container) {
      resizeObserver.observe(container);
    }
  }
});

onUnmounted(() => {
  if (resizeObserver) {
    resizeObserver.disconnect();
  }
  if (loadTimeout.value) {
    clearTimeout(loadTimeout.value);
  }
});
</script>

<style scoped>
.iframe-loading {
  gap: 12px;
}

.loading-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #409eff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

.loading-text {
  color: #666;
  font-size: 14px;
}

.iframe-error {
  gap: 12px;
}

.error-icon {
  font-size: 48px;
}

.error-message {
  color: #666;
  font-size: 14px;
  max-width: 400px;
  line-height: 1.5;
  text-align: left;
}

.error-message h3 {
  color: #333;
  margin: 0 0 10px 0;
  text-align: center;
}

.error-message h4 {
  color: #555;
  margin: 15px 0 5px 0;
  font-size: 13px;
}

.error-message ul {
  margin: 5px 0;
  padding-left: 0;
  list-style: none;
}

.error-message li {
  margin: 3px 0;
  font-size: 12px;
}

.error-tips {
  background: #f8f9fa;
  padding: 10px;
  border-radius: 4px;
  margin-top: 10px;
  border-left: 3px solid #409eff;
}

.retry-button {
  background-color: #409eff;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.retry-button:hover {
  background-color: #337ecc;
}

.retry-button:active {
  background-color: #2b6cb0;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .error-message {
    font-size: 12px;
    max-width: 250px;
  }

  .loading-text {
    font-size: 12px;
  }
}
</style>
